/*! \file Graph.hpp */

#ifndef GRAPH_HPP_INCLUDED
#define GRAPH_HPP_INCLUDED

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/clustering_coefficient.hpp>
#include <boost/graph/exterior_property.hpp>

#include <string>
#include <boost/tuple/tuple_comparison.hpp>
#include <utility>
#include <vector>
#include <map>


/**
 * Defines a graph object. This typedef defines an undirected boost graph which is represented as a boost::adjacency_list where
 * each vertex has the boost property vertex_name set to an unsigned int and has the graph_name boost property set
 * to a std::string.
 */
typedef boost::adjacency_list
<
    boost::setS,  ///< The edge container type is a boost::set
    boost::vecS,  ///< The vertex container type is a boost::vector
    boost::undirectedS, ///< The graph is undirected
    boost::property<boost::vertex_name_t, unsigned int>, ///< Each vertex has a vertex_name property of the type unsigned int.
    boost::property<boost::edge_index_t, unsigned int>, ///< Each edge has an index which is an unsigned int
    boost::property<boost::graph_name_t, std::string> ///< Each graph has a name property which is a std::string
> Graph;

/// Defines a vertex iterator
typedef boost::graph_traits<Graph>::vertex_iterator Iter_t;
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
typedef boost::graph_traits<Graph>::edge_descriptor Edge;



/** A boost::tuple describing an edit operation of a graph.
* The first boolean is the type of the edit operation, true means it is an vertex addition operation, false
* means it is an edge addition operation.
* If the edit operation is a vertex addition op, then the first integer is the ID of an existing vertex
* in the graph and the second integer is the id of the new vertex to be added.
* If the edit operation is an edge addition, then the integers are the IDs of the vertices between which to add an edge.
*/
typedef boost::tuple<bool, unsigned int, unsigned int> EditOp;


/**
 * This defines a collection of vertex mappings, for example after doing
 * subgraph isomorphism on a graph with non-unique node labelings.
 */
typedef std::vector< std::map<Vertex, Vertex> > VertexMappings;


/**
 * A mapping from an edit operation to a double. This type defines a discrete probability distribution from an edit operation
 * to a double (the probability value). The values sum to 1.
 */
typedef std::map<EditOp, double > EditOpDist;

/**
 * This typedef defines a mapping from a unsigned int -> vector<double>, which is basically
 * a mapping from a category ID to a discrete distribution over the number of edges of this category.
 */
typedef std::map< unsigned int, std::vector<double> > CategoryDegreeDist;


// A[Corr][Off][50] = 0.3
typedef std::map<int, std::map<int, std::vector<double> > > CategToCategDist;

/// The clustering property, container, and map define the containment
/// and abstract accessor for the clustering coefficients of vertices.
typedef boost::exterior_vertex_property<Graph, float> ClusteringProperty;
typedef ClusteringProperty::container_type ClusteringContainer;
typedef ClusteringProperty::map_type ClusteringMap;

/*! \mainpage
 *
 * \section intro_sec Introduction
 *
 * This documentation describes an API for loading, manipulating and doing prediction on unique node labeled graphs.
 * The graphs are represented using the Boost graph library and the API provides fascilities for loading what is called a graph database.
 * A graph database is simply a set of graphs, that can be used for doing prediction. Prediction in this sense is defined as, given a subgraph
 * of some larger, unknown graph, what is the most likely larger subgraph of the unknown graph that also contains the subgraph already observed?
 * The predictors in this API will provide the answer to this given a graph database, and it will return a discrete probability distribution
 * over the so called edit operations of the input graph. This is encapsulated in the class EditOpDist, which simply maps a given edit operation
 * to a floating point value, all the operations summing to 1.
 * An edit operation is simply either adding a new vertex to the graph and connecting it to some other existing vertex, or adding an edge between
 * two existing vertices.
 * The API also provides functions for graph manipulation, such as removing vertain vertices, merging vertices, blacklisting and serializing.
 *
 */


#endif // GRAPH_HPP_INCLUDED
